package org.wxd.common.utils.http;

import com.google.common.collect.Lists;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.wxd.common.utils.Assert;
import org.wxd.common.utils.JsonUtil;

import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;

/**
 * Created by wangxd on 2016/12/14.
 */
public class HttpRequestParam {


    private String url;
    private String encoding;
    private boolean isStream;
    private OutputStream out;
    private HttpMethod method;
    private HttpContentType contentType;
    private Object params;

    public HttpRequestParam(Builder builder) {
        Assert.notNull(builder.method,"method must not null.");
        Assert.notNull(builder.url,"url must not null.");
        this.url = builder.url;
        this.isStream = builder.isStream;
        this.out = builder.out;
        this.encoding = builder.encoding;
        this.method = builder.method;
        this.contentType = builder.contentType;
        this.params = builder.params;
    }

    public HttpMethod method() {
        return method;
    }

    public String encoding() {
        return encoding;
    }

    public boolean isStream() {
        return isStream;
    }

    public OutputStream out() {
        return out;
    }

    public HttpContentType contentType() {
        return contentType;
    }

    public String url() {
        return url;
    }

    protected String toGetUrl() {
        StringBuilder param = new StringBuilder(this.url).append("?");
        Arrays.asList(params.getClass().getDeclaredFields()).forEach(f -> {
            f.setAccessible(true);
            try {
                Object val = f.get(params);
                if (val != null) param.append(f.getName()).append("=").append(val).append("&");
            } catch (IllegalAccessException e) {
                throw new HttpClientException(e.getMessage(), e);
            }
        });
        return param.deleteCharAt(param.length() - 1).toString();
    }

    protected String toPostWithJson(){
        return JsonUtil.stringify(this.params);
    }

    protected List<NameValuePair> toPostParams() {
        List<NameValuePair> results = Lists.newArrayList();
        Arrays.asList(params.getClass().getDeclaredFields()).parallelStream().forEach(f -> {
            f.setAccessible(true);
            try {
                Object val = f.get(params);
                if (val != null) results.add(new BasicNameValuePair(f.getName(), val.toString()));
            } catch (IllegalAccessException e) {
                throw new HttpClientException(e.getMessage(), e);
            }
        });
        return results;
    }


    public static Builder newBuilder() {
        return new Builder();
    }

    public static class Builder {
        String url;
        String encoding = "UTF-8";
        boolean isStream;
        OutputStream out;
        HttpMethod method;
        HttpContentType contentType;
        Object params;

        public Builder encoding(String encoding) {
            this.encoding = encoding;
            return this;
        }

        public HttpRequestParam build() {
            return new HttpRequestParam(this);
        }

        public Builder url(String url) {
            this.url = url;
            return this;
        }

        public Builder stream(boolean isStream,OutputStream stream){
            this.isStream = isStream;
            this.out = stream;
            return this;
        }



        public Builder method(HttpMethod method) {
            this.method = method;
            return this;
        }

        public Builder contentType(HttpContentType contentType) {
            this.contentType = contentType;
            return this;
        }

        public Builder params(Object params) {
            this.params = params;
            return this;
        }
    }

}
